package cn.com.headfree.recordlog.service.impl;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import cn.com.headfree.entity.*;
import cn.com.headfree.entity.isc.User;
import cn.com.headfree.util.FieldMeta;
import com.gta.edu.sdk.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gta.edu.sdk.base.service.impl.BaseServiceImpl;
import com.gta.edu.sdk.common.dto.Page;
import com.gta.edu.sdk.util.IdGen;

import cn.com.headfree.recordlog.dao.IRecordLogDao;
import cn.com.headfree.recordlog.service.IRecordLogService;

/**  
 * @Title  RecordLogServiceImpl.java   
 * @Package cn.com.headfree.recordlog.service.impl   
 * @Description 业务记录操作日志信息serviceImpl
 * @author yangwang 
 * @date  2020年7月3日 下午3:44:07   
 */
@Service("recordLogService")
public class RecordLogServiceImpl extends BaseServiceImpl<TRecordOptLog> implements IRecordLogService {

	private static final Logger LOG = LogManager.getLogger(RecordLogServiceImpl.class);
	
	@Autowired
	private IRecordLogDao recordLogDao;

	/**
	 * 保存记录
	 * @param user
	 * @param record
	 *  */
	@Transactional
	@Override
	public void save(User user,TRecordOptLog record) {
		if((null != record)&&(StringUtils.isNotBlank(record.getRecordId()))) {
			record.setId(IdGen.uuid());
			record.setOptTime(new Date());
			if((null != user)&&(StringUtils.isNotBlank(user.getId()))) {
				record.setOptUserId(user.getFax());
				record.setOptUserName(user.getName());
			}
			
			recordLogDao.insert(record);
		}
	}
	
	/**
	 * 获取记录列表
	 * @param record
	 * @return List<TRecordOptLog>
	 *  */
	@Override
	public List<TRecordOptLog> getList(TRecordOptLog record){
		List<TRecordOptLog> recordList = recordLogDao.getList(record);
		if((null != recordList)&&(0 < recordList.size())){
			List<TSysDictionaryInfo> dicList = recordLogDao.getDictionarys("jlczlx");
			if((null != dicList)&&(0 < dicList.size())) {
				for(TRecordOptLog r:recordList) {
					if((null != r)&&(StringUtils.isNotBlank(r.getId()))&&(StringUtils.isNotBlank(r.getOptType()))) {
						Optional<TSysDictionaryInfo> opt = dicList.stream().filter(d -> ((null !=d)&&(StringUtils.isNotBlank(d.getValue()))&&(StringUtils.equals(d.getValue(), r.getOptType())))).findFirst();
						if(opt.isPresent()) {
							r.setOptTypeName(opt.get().getName());
						}
					}
				}
			}
		}else {
			recordList = null;
		}
		return recordList;
	}
	
	/**
	 * 获取分页记录信息
	 * @param record
	 *  */
	@Override
	public void getPage(Page<TRecordOptLog> page,TRecordOptLog record) {
		recordLogDao.getPage(page, record);
		if((null != page)&&(null != page.getResult())&&(0 < page.getResult().size())){
			List<TSysDictionaryInfo> dicList = recordLogDao.getDictionarys("jlczlx");
			if((null != dicList)&&(0 < dicList.size())) {
				for(TRecordOptLog r:page.getResult()) {
					if((null != r)&&(StringUtils.isNotBlank(r.getId()))&&(StringUtils.isNotBlank(r.getOptType()))) {
						Optional<TSysDictionaryInfo> opt = dicList.stream().filter(d -> ((null !=d)&&(StringUtils.isNotBlank(d.getValue()))&&(StringUtils.equals(d.getValue(), r.getOptType())))).findFirst();
						if(opt.isPresent()) {
							r.setOptTypeName(opt.get().getName());
						}
					}
				}
			}
		}
	}

	@Override
	public void save(Object newObject, Object oldObject,TRecordOptLog record,User user,String state,String fromType) {
		Map<String, List<Object>> map = compareFields(newObject,oldObject);
		StringBuffer sb = new StringBuffer();
		//state为0表示修改，为1表示审核时修改
		if(state.equals("1")){//审核时修改数据
			if(!StringUtil.isNullOrEmpty(record.getOptContent())){
				if(map.size() > 0){
					sb.append(record.getOptContent()+"。并修改了数据");
				}else{
					sb.append(record.getOptContent());
				}
			}
		}else{
			//fromType为0表示在pc端修改的，为1表示是移动端修改的
			if(fromType != null && fromType.equals("1")){//移动端修改
				sb.append(user.getName()+"在移动端修改了数据");
			}else{
				sb.append(user.getName()+"修改了数据");
			}
		}

		int i = 0;
		String tPartRankListMessage = null;
		String tSdtPrentInfoMessage = null;
		boolean flag = false;
		for(String key : map.keySet()){
			if(i == 0){
				sb.append("，");
			}
			i++;
			List<String> values = (List<String>)(List)map.get(key);
			if(values != null && values.size() > 1){
				flag = true;
				String value1 = values.get(0)+"";
				String value2 = values.get(1)+"";
				if(StringUtil.isNullOrEmpty(value1)){
					value1 = "无";
				}
				if(StringUtil.isNullOrEmpty(value2)){
					value2 = "无";
				}
				sb.append(key+"由"+value1+"修改为"+value2);
				if(map.size() > i){
					sb.append("，");
				}
			}else{
				if(key.equals("tPartRankList")){//多人参与类型的参与人比较
					String value = values.get(0)+"";
//					sb.append(value);
					tPartRankListMessage = value;
				}
				if(key.equals("tSdtPrentInfo")){//导师带徒的徒弟信息比较
					String value = values.get(0)+"";
//					sb.append(value);
					tSdtPrentInfoMessage = value;
				}
			}
		}
		if(!StringUtil.isNullOrEmpty(tPartRankListMessage)){
			if(flag){
				sb.append("，");
			}
			sb.append(tPartRankListMessage);
		}
		if(!StringUtil.isNullOrEmpty(tSdtPrentInfoMessage)){
			if(flag){
				sb.append("，");
			}
			sb.append(tSdtPrentInfoMessage);
		}
		LOG.info("============================匹配完成================================="+sb);
		record.setOptContent(sb.toString());
		save(user,record);
	}

	public Map<String, List<Object>> compareFields(Object newObj, Object oldObj) {
		try{
			Map<String, List<Object>> map = new HashMap<String, List<Object>>();
			if (newObj.getClass() == oldObj.getClass()) {// 只有两个对象都是同一类型的才有可比性
				Class clazz = newObj.getClass();
				// 获取object的属性描述
				PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,Object.class).getPropertyDescriptors();
				Field[] at = clazz.getDeclaredFields();
				for (PropertyDescriptor pd : pds) {// 这里就是所有的属性了
					String fieldName = pd.getName();// 字段名
					String zwName = null;//字段中文名
					for(Field fd:at){
						FieldMeta fm = fd.getAnnotation(FieldMeta.class);
						if(fm != null){
							if(fm.name().equals(fieldName)){
								zwName = fm.description();
							}
						}
					}
					LOG.info("===============字段中文名为=============="+zwName);
					if(zwName != null){
						Method readMethod = pd.getReadMethod();// get方法
						// 在obj1上调用get方法等同于获得obj1的属性值
						Object o1 = readMethod.invoke(newObj);
						// 在obj2上调用get方法等同于获得obj2的属性值
						Object o2 = readMethod.invoke(oldObj);
						List<Object> list = new ArrayList<Object>();
						if(fieldName != null && fieldName.equals("tPartRankList")){//多名参与人类型的人员处理
							String tPartRankMessage = compareTPartRankFields(o1,o2);
							if(!StringUtil.isNullOrEmpty(tPartRankMessage)){
								list.add(tPartRankMessage);
								map.put("tPartRankList",list);
							}
						}else if(fieldName != null && fieldName.equals("tSdtPrentInfo")){//导师带徒类型的徒弟处理
							String tSdtPrentMessage = compareTSdtPrentInfoFields(o1,o2);
							if(!StringUtil.isNullOrEmpty(tSdtPrentMessage)){
								list.add(tSdtPrentMessage);
								map.put("tSdtPrentInfo",list);
							}
						}else{
							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
							if(o1 instanceof Date){
								o1 = sdf.format(o1);
							}
							if(o2 instanceof Date){
								o2 = sdf.format(o2);
							}
							if(o1 instanceof Integer){
								o1 = o1+"";
							}
							if(o2 instanceof Integer){
								o2 = o2+"";
							}
							if(o1 == null && o2 == null){
								continue;
							}else if(o1 == null && o2 != null){
								list.add(o2);
								list.add("无");
								map.put(zwName, list);
								continue;
							}else if(o1 != null && o2 == null){
								list.add("无");
								list.add(o1);
								map.put(zwName, list);
								continue;
							}
							if (!o1.equals(o2)) {// 比较这两个值是否相等,不等就可以放入map了
								list.add(o2);
								list.add(o1);
								map.put(zwName, list);
							}
						}
					}
				}
			}
			return map;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}

	//比较有多个参与人类型的参与人修改情况
	public String compareTPartRankFields(Object newObj, Object oldObj) {
		try{
			List<TPartRank> newPartRanks = (List<TPartRank>) newObj;
			List<TPartRank> oldPartRanks = (List<TPartRank>) oldObj;
			List<TPartRank> list = new ArrayList<>();
			StringBuffer sb = new StringBuffer();
			for(TPartRank newRank:newPartRanks){
				boolean flag = false;
				if(!StringUtil.isNullOrEmpty(newRank.getUserName())) {
					String userName = "";
					if(newRank.getUserName().contains("【")){
						userName = newRank.getUserName().substring(0, newRank.getUserName().indexOf("【"));
					}else{
						userName = newRank.getUserName();
					}
					for (TPartRank oldRank : oldPartRanks) {
						if (newRank.getErpNo().equals(oldRank.getErpNo())) {//新的人员里面包含老的人员
							if (newRank.getRole() == null) {
								newRank.setRole("无");
							}
							if (oldRank.getRole() == null) {
								oldRank.setRole("无");
							}
							if (!(newRank.getRole().equals(oldRank.getRole()))) {//修改了角色
								sb.append(userName + "的角色由" + oldRank.getRoleName() + "修改为" + newRank.getRoleName()).append("，");
							}
							if (!(newRank.getRank().equals(oldRank.getRank()))) {//修改了排名
								sb.append(userName + "的排名由" + oldRank.getRank() + "修改为" + newRank.getRank()).append("，");
							}
							flag = true;
							list.add(oldRank);
						}
					}
					if (!flag) {//新的人员里面不包含老的人员
						sb.append("新增了参与人员" + userName).append("，");
					}
				}
				LOG.info(newRank.getErpNo()+"=============="+newRank.getUserName()+"================"+newRank.getRoleName());
			}
			oldPartRanks.removeAll(list);
			for (TPartRank rank:oldPartRanks){
				if(!StringUtil.isNullOrEmpty(rank.getUserName())) {
					String userName = "";
					if(rank.getUserName().contains("【")){
						userName = rank.getUserName().substring(0, rank.getUserName().indexOf("【"));
					}else{
						userName = rank.getUserName();
					}
					sb.append(userName + "从参与人名单中去除").append("，");
				}
			}
			if(sb.length() > 0){
				String str = sb.toString();
				return str.substring(0,str.length() -1);
			}
			return null;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}

	//比较徒弟信息修改情况
	public String compareTSdtPrentInfoFields(Object newObj, Object oldObj) {
		try{
			List<TSdtPrentInfo> newTSdtPrents = (List<TSdtPrentInfo>) newObj;
			List<TSdtPrentInfo> oldTSdtPrents = (List<TSdtPrentInfo>) oldObj;
			List<TSdtPrentInfo> list = new ArrayList<>();
			StringBuffer sb = new StringBuffer();
			for(TSdtPrentInfo newRank:newTSdtPrents){
				boolean flag = false;
				List<TSdtAward> newAwards = newRank.gettSdtAwardList();
				List<String> newIdList = newAwards.stream().map(p -> p.getItemId()).collect(Collectors.toList());
				List<String> newAwardList = newAwards.stream().map(p -> p.getAward()).collect(Collectors.toList());
				if(!StringUtil.isNullOrEmpty(newRank.getUserName())) {
					String userName = "";
					if(newRank.getUserName().contains("【")){
						userName = newRank.getUserName().substring(0, newRank.getUserName().indexOf("【"));
					}else{
						userName = newRank.getUserName();
					}
					for (TSdtPrentInfo oldRank : oldTSdtPrents) {
						if (newRank.getErpNo().equals(oldRank.getErpNo())) {//新的人员里面包含老的人员
							List<TSdtAward> oldAwards = oldRank.gettSdtAwardList();
							List<String> oldIdList = oldAwards.stream().map(p -> p.getItemId()).collect(Collectors.toList());
							List<String> oldAwardList = oldAwards.stream().map(p -> p.getAward()).collect(Collectors.toList());
							if(oldAwardList != null && oldAwardList.size() > 0) {
								for(int i=0;i<oldIdList.size();i++){
									if (!newIdList.contains(oldIdList.get(i))) {//如果该徒弟新的奖项里面不包含老的奖项，则表明该老的奖项已经被去除
										sb.append(userName + "所获奖项" + oldAwardList.get(i) + "去除").append("，");
									}
								}
							}
							if(newIdList != null && newIdList.size()>0){
								for (int i=0;i<newIdList.size();i++) {
									if (oldIdList.size() == 0 || !oldIdList.contains(newIdList.get(i))) {//如果该徒弟老的奖项里面不包含新的奖项，则表明该新的奖项是新增的
										sb.append(userName + "所获奖项新增了" + newAwardList.get(i)).append("，");
									}
								}
							}
							flag = true;
							list.add(oldRank);
						}
					}
					if (!flag) {//新的人员里面不包含老的人员
						sb.append("新增了徒弟" + userName).append("，");
					}
				}
			}
			oldTSdtPrents.removeAll(list);
			for (TSdtPrentInfo rank:oldTSdtPrents){
				if(!StringUtil.isNullOrEmpty(rank.getUserName())) {
					String userName = "";
					if(rank.getUserName().contains("【")){
						userName = rank.getUserName().substring(0, rank.getUserName().indexOf("【"));
					}else{
						userName = rank.getUserName();
					}
					sb.append(userName + "从徒弟名单中去除").append("，");
				}
			}
			if(sb.length() > 0){
				String str = sb.toString();
				return str.substring(0,str.length() -1);
			}
			return null;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}




}
